package com.liuyjy.encryptDecrypt;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.io.IOException;

/**
 * @Author liuyjy
 * @Date 2025/2/20 9:42
 * @Description: 动态序列化器
 **/
public class DynamicCryptoSerializer extends JsonSerializer<Object> {
    private final CryptoProvider provider;
    private final Encrypt encryptMeta;
    private final Decrypt decryptMeta;

    public DynamicCryptoSerializer(CryptoProvider provider, Encrypt encryptMeta) {
        this.provider = provider;
        this.encryptMeta = encryptMeta;
        this.decryptMeta = null;
    }

    public DynamicCryptoSerializer(CryptoProvider provider, Decrypt decryptMeta) {
        this.provider = provider;
        this.decryptMeta = decryptMeta;
        this.encryptMeta = null;
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider)
            throws IOException {
        if (value == null) {
            gen.writeNull();
            return;
        }

        // 动态检查开关状态
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            Boolean enabled = (Boolean) requestAttributes.getAttribute(
                    "CRYPTO_ENABLED", RequestAttributes.SCOPE_REQUEST);
            if (enabled != null && enabled) {
                try {
                    String processedValue = processValue(value.toString());
                    gen.writeString(processedValue);
                    return;
                } catch (Exception e) {
                    throw new JsonMappingException(gen, "Crypto process failed", e);
                }
            }
        }

        // 如果开关未启用，直接写入原始值
        gen.writeObject(value);
    }

    private String processValue(String value) {
        if (encryptMeta != null) {
            return provider.encrypt(value, encryptMeta);
        }
        if (decryptMeta != null) {
            return provider.decrypt(value, decryptMeta);
        }
        return value;
    }
}
